#!/usr/bin/python3

import yaml
import json
import sys
import os
import getopt


def printUsage():
    print("Generate configtx.yaml\nUsage:")
    print("    gen_configtxg_from_template.py -o <orderer_num> -p <peer_num>")
    print(
        "    or: gen_configtxg_from_template.py --orderer_num=<orderer_num> --peer_num=<peer_num>"
    )


def parseArgs(argv):
    global orderer_num
    global peer_num
    opts, args = getopt.getopt(argv[1:], "ho:p:", ["help", "orderer_num=", "peer_num="])

    if len(opts) > 2 or len(args) != 0:
        print("Invalid paramater")
        sys.exit()
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            printUsage()
            sys.exit()
        elif opt in ("-o", "--orderer_num"):
            orderer_num = int(arg)
        elif opt in ("-p", "--peer_num"):
            peer_num = int(arg)


def fill_organizations():
    global configtx
    for i in range(1, peer_num + 1):
        org_data = {
            "Name": f"Org{i}MSP",
            "ID": f"Org{i}MSP",
            "MSPDir": f"../crypto-config/peerOrganizations/org{i}.demo.com/msp",
            "Policies": {
                "Readers": {
                    "Type": "Signature",
                    "Rule": f"OR('Org{i}MSP.admin', 'Org{i}MSP.peer', 'Org{i}MSP.client')",
                },
                "Writers": {
                    "Type": "Signature",
                    "Rule": f"OR('Org{i}MSP.admin', 'Org{i}MSP.client')",
                },
                "Admins": {"Type": "Signature", "Rule": f"OR('Org{i}MSP.admin')"},
            },
            "AnchorPeers": [
                {"Host": f"peer0.org{i}.demo.com", "Port": peer_start_port + i}
            ],
        }
        configtx["Organizations"].append(org_data)


def fill_capabilities():
    global configtx
    configtx["Capabilities"]["Channel"] = {f"V{channel_version}": True}
    configtx["Capabilities"]["Orderer"] = {f"V{orderer_version}": True}
    configtx["Capabilities"]["Application"] = {f"V{application_version}": True}


def fill_orderer():
    global configtx
    addresses = [
        f"orderer{i}.demo.com:{orderer_start_port+i-1}"
        for i in range(1, orderer_num + 1)
    ]
    configtx["Orderer"]["Addresses"] = addresses

    consenters = []
    for i in range(1, orderer_num + 1):
        consenters.append(
            {
                "Host": f"orderer{i}.demo.com",
                "Port": orderer_start_port + i - 1,
                "ClientTLSCert": f"../crypto-config/ordererOrganizations/demo.com/orderers/orderer{i}.demo.com/tls/server.crt",
                "ServerTLSCert": f"../crypto-config/ordererOrganizations/demo.com/orderers/orderer{i}.demo.com/tls/server.crt",
            }
        )
    configtx["Orderer"]["EtcdRaft"]["Consenters"] = consenters


def fill_channel():
    configtx["Channel"]["Capabilities"] = configtx["Capabilities"]["Channel"]


def fill_application():
    configtx["Application"]["Capabilities"] = configtx["Capabilities"]["Application"]


def fill_profiles():
    global configtx
    organizations = []
    for i in range(1, peer_num + 1):
        organizations.append(configtx["Organizations"][i])
    # print(configtx["Capabilities"]["Orderer"])
    configtx["Profiles"]["OrgsOrdererGenesis"]["Capabilities"] = configtx[
        "Capabilities"
    ]["Channel"]
    configtx["Profiles"]["OrgsOrdererGenesis"]["Orderer"]["Addresses"] = configtx[
        "Orderer"
    ]["Addresses"]
    configtx["Profiles"]["OrgsOrdererGenesis"]["Orderer"]["Capabilities"] = configtx[
        "Capabilities"
    ]["Orderer"]
    configtx["Profiles"]["OrgsOrdererGenesis"]["Consortiums"]["SampleConsortium"][
        "Organizations"
    ] = organizations
    configtx["Profiles"]["OrgsChannel"]["Capabilities"] = configtx["Capabilities"][
        "Channel"
    ]
    configtx["Profiles"]["OrgsChannel"]["Application"]["Organizations"] = organizations
    configtx["Profiles"]["OrgsChannel"]["Application"]["Capabilities"] = configtx[
        "Capabilities"
    ]["Application"]


orderer_num = 1
peer_num = 4
peer_start_port = 7100
orderer_start_port = 7050
channel_version = "1_4_3"
orderer_version = "1_4_2"
application_version = "1_4_2"
configtx = {}

if __name__ == "__main__":
    parseArgs(sys.argv)

    with open("configtx-template.yaml", "r", encoding="utf-8") as file:
        configtx = yaml.safe_load(file)

    fill_organizations()
    fill_capabilities()
    fill_orderer()
    fill_channel()
    fill_application()
    fill_profiles()

    with open("configtx.yaml", "w", encoding="utf8") as f:
        yaml.dump(
            configtx,
            f,
            default_flow_style=False,
            allow_unicode=True,
            sort_keys=False,
            indent=4,
        )
